import modelExtend from 'dva-model-extend'
import {
  tree,
  store,
  update,
  destroy,
  bindUser,
  unbindUser,
  getUserIds,
  getTenantBoundUserIds,
  sortAs,
} from 'services/organization'
import {levelSort} from 'services/distributor'
import { listByUserIds as getUserByIds } from 'services/security/user'
import { lwjPageModel } from 'utils/model'
import { getByField } from 'utils/helpers'
import { ROOT_ID } from 'utils/organizationConstant'
import { Modal, notification, message } from 'antd'
import { routerRedux } from 'dva/router'

export default modelExtend(lwjPageModel, {
  namespace: 'organization',
  state: {
    tree: [],
    currentItem: {},
    parentItem: {},
    modalVisible: false,
    type: 'create',
    userIds: [],
    users: [],
    usersBackup: [],
    userSelectModalVisible: false,
    pageOptions: {
      sort: 'createTime',
      order: 'DESC'
    },
    searchKeyword: ''
  },
  subscriptions: {
    setup ({dispatch, history}) {
      history.listen(({pathname}) => {
        /**
         * 列表页的监听
         */
        if (pathname === '/organization') {
          dispatch({type: 'getTree', payload: {}})
          // 清掉state中的树信息
          dispatch({type: 'clear'})
        }
        if (pathname === '/user') {
          // 清掉state中的树信息
          dispatch({type: 'setSearchKeyword', payload: {keyword: ''}})
        }
      })
    },
  },
  effects: {
    * getTree ({payload}, {call, put}) {
      const data = yield call(tree, payload)

      yield put({type: 'tree', payload: data.result})
    },

    * onChoose ({payload}, {call, put}) {
      const {id} = payload
      if (typeof id !== 'undefined') {
        const res = yield call(getUserIds, id)
        let userIds = res.result
        if (!res.success) {
          userIds = []
        }
        const users = yield call(getUserByIds, userIds)

        yield put({
          type: 'bindUser', payload: {
            userIds: [],
            users: users.result,
            usersBackup: users.result,
          }
        })
      }

      yield put({type: 'choose', payload: payload})
    },

    * onStore ({payload}, {call, put}) {
      const res = yield call(store, payload)
      if (res.success) {
        yield put({type: 'hideModal'})
        yield put({type: 'getTree'})
      } else {
        throw res
      }
    },

    * onUpdate ({payload}, {call, put}) {
      const res = yield call(update, payload)
      if (res.success) {
        yield put({type: 'hideModal'})
        yield put({type: 'getTree'})
        payload.version += 1 // 乐观锁+1
        yield put({type: 'choose', payload: payload})
      } else {
        throw res
      }
    },

    * onDelete ({payload}, {call, put}) {
      const {id, version} = payload
      const res = yield call(destroy, id, version)
      if (res.success) {
        yield put({type: 'getTree'})
      } else {
        throw res
      }
    },

    * onSelectUser ({payload}, {call, put}) {
      yield put({type: 'selectModal', payload: {}})
    },

    * onBindUser ({payload}, {call, put}) {
      const {id, ids} = payload

      const res = yield call(bindUser, {orgId: id, ids: ids})
      if (res.success) {
        yield put({type: 'onChoose', payload: payload})
        yield put({type: 'hideModal'})
      } else {
        throw res
      }
    },

    * onUnbindUser ({payload}, {call, put}) {
      const {id, ids} = payload
      const res = yield call(unbindUser, {orgId: id, ids: ids})
      if (res.success) {
        yield put({type: 'onChoose', payload: payload})
        notification.open({
          message: '成功',
          description: '解绑人员成功',
        })
      } else {
        throw res
      }
    },

    * onDrag ({payload}, {call, put}) {
      const {tree, dragNode,levelDrop,node} = payload
      if(levelDrop){
        yield call(levelSort, node.id, dragNode.id)
        yield put(routerRedux.push('/organization'));
        return
      }
      const ids = tree.filter(item => item.parentId === dragNode.pid).map(item => item.id)
      const res = yield call(sortAs, dragNode.pid, ids)
      if (!res.success) {
        message.error('更改优先级失败')
        yield put({type: 'getTree'})
      }
    },
  },
  reducers: {
    /**
     * 处理state中的tree
     * @param state
     * @param payload
     * @return {{}}
     */
    tree (state, {payload}) {
      if (Array.isArray(payload)) {
        let rootIndex = null
        for (let i = 0; i < payload.length; ++i) {
          if (payload[i].id === ROOT_ID) {
            rootIndex = i
          }
        }

        if (rootIndex !== null) {
          payload.splice(rootIndex, 1)
        }
      }

      state.tree = payload.map(item => {
        item.enabled = true
        return item
      })

      return {
        ...state
      }
    },

    clear (state, {payload}) {
      state.currentItem = {}
      state.parentItem = {}
      state.users = []
      state.userIds = []
      state.searchKeyword = ''

      return {
        ...state
      }
    },

    /**
     * 选择
     * @param state
     * @param payload
     * @return {{}}
     */
    choose (state, {payload}) {
      state.currentItem = payload

      return {
        ...state
      }
    },

    bindUser (state, {payload}) {
      return {
        ...state,
        ...payload
      }
    },

    /**
     * 打开添加的modal
     * @param state
     * @param payload
     * @return {{}}
     */
    create (state, {payload}) {
      state.modalVisible = true
      state.type = 'create'
      // 寻找一下父级的对象
      let parentItem = getByField(state.tree, 'id', state.currentItem.id)
      if (Object.keys(parentItem).length === 0) {
        parentItem = getByField(state.tree, 'parentId', ROOT_ID)
      }
      state.parentItem = parentItem

      return {
        ...state
      }
    },

    /**
     * 打开编辑的modal
     * @param state
     * @param payload
     * @return {{}}
     */
    edit (state, {payload}) {
      if (!_.isEmpty(state.currentItem)) {
        state.modalVisible = true
        state.type = 'update'
        // 寻找一下父级的对象
        state.parentItem = getByField(state.tree, 'id', state.currentItem.parentId)
      }

      return {
        ...state
      }
    },

    queryUserSuccess (state, {payload}) {
      return {
        ...state,
        userItems: payload.content,
        userPagination: {
          ...state.resourcePagination,
          current: payload.number + 1,
          total: payload.totalElements
        }
      }
    },

    selectModal (state, {payload}) {
      state.userSelectModalVisible = true
      return {
        ...state
      }
    },

    createSelectUserIds (state, {payload}) {
      state.userIds = payload

      return {
        ...state
      }
    },

    dragNode (state, {payload}) {
      const {dragNode, node, dropToGap, dropPosition} = payload
      if (dropToGap) {
        const {props: {pos}} = node

        const posArr = pos.split('-')
        const position = Number(posArr.pop()) > dropPosition ? 'up' : 'down'
        let dragIndex = state.tree.findIndex(item => item.id === dragNode.props.id)
        let dragItem = state.tree.splice(dragIndex, 1)
        let targetIndex = state.tree.findIndex(item => item.id === node.props.id)

        switch (position) {
          case 'down':
            state.tree.splice(Number(targetIndex) + 1, 0, dragItem[0])
            break
          case 'up':
            state.tree.splice(Number(targetIndex), 0, dragItem[0])
            break
          default:
            throw new Error('参数错误')
        }
      }

      return {
        ...state
      }
    },

    /**
     * 隐藏所有modal
     * @param state
     * @param payload
     * @return {{}}
     */
    hideModal (state, {payload}) {
      state.modalVisible = false
      state.userSelectModalVisible = false

      return {
        ...state
      }
    },

    setSearchKeyword (state, {payload}) {
      const {keyword} = payload

      state.searchKeyword = keyword

      return {
        ...state
      }
    },

    searchUserList (state, {payload}) {
      // 搜索备份中的数据
      if (! _.isEmpty(payload)) {
        state.users = state.usersBackup.filter(item => {
          let bolt = false

          if ('displayName' in payload) {
            bolt = item.displayName.includes(payload.displayName)
            if (! bolt) {
              return bolt
            }
          }

          if ('mobile' in payload) {
            bolt = item.mobile.includes(payload.mobile)
            if (! bolt) {
              return bolt
            }
          }

          return bolt
        })
      } else {
        state.users = state.usersBackup
      }

      return {
        ...state
      }
    },
  },
})
